home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / COMMS / C035.ZIP / JMODEM_C.C < prev    next >
Text File  |  1990-02-17  |  8KB  |  145 lines

  1. /****************************************************************************/
  2. /*   FILE JMODEM_C.C                                                        */
  3. /*   Created 11-JAN-1990                   Richard B. Johnson               */
  4. /*                                         405 Broughton Drive              */
  5. /*                                         Beverly, Massachusetts 01915     */
  6. /*                                         BBS (508) 922-3166               */
  7. /*                                                                          */
  8. /*   File I/O                                                               */
  9. /*   file_io();                                                             */
  10. /*   All of the file I/O is called from this one block to ease portability  */
  11. /*                                                                          */
  12. /****************************************************************************/
  13. #include <stdio.h>                      /* Used for NULL                   */
  14. #include <io.h>                         /* Ysed for Unix / DOS type files  */
  15. #include <fcntl.h>                      /* Used for O_BINARY, etc          */
  16. #include <string.h>                     /* Used for _strchr(), etc         */
  17. #include "jmodem.h"                     /* Used for JMODEM primatives      */
  18.  
  19. /*   Note:                                                                  */
  20. /*   I originally used fopen();, fclose();, fread();, and fwrite(); the     */
  21. /*   default C stream-I/O files. However, a bug in Microsoft's implementa-  */
  22. /*   tion results in corruption of files larger than about 512k. The bug    */
  23. /*   inserts a null into the  files every approximately 512k.               */
  24. /*   Therefore, I changed to the UNIX-style disk I/O.                       */
  25. /*                                                                          */
  26. /****************************************************************************/
  27. /* Merged from \include\sys\stat.h because improperly organized header-file */
  28. /* REQUIRES that two other files be included first! Thanks, Microsoft...    */
  29. #define S_IFMT      0170000         /* file type mask */
  30. #define S_IFDIR     0040000         /* directory */
  31. #define S_IFCHR     0020000         /* character special */
  32. #define S_IFREG     0100000         /* regular */
  33. #define S_IREAD     0000400         /* read permission, owner */
  34. #define S_IWRITE    0000200         /* write permission, owner */
  35. #define S_IEXEC     0000100         /* execute/search permission, owner */
  36. /****************************************************************************/
  37.  
  38. unsigned short file_io(command, handle, buffer, len)
  39. unsigned short command;                         /* Read/write/open, etc.  */
  40. short *handle;                                  /* File handle            */
  41. unsigned char **buffer;                         /* Working buffer pointer */
  42. unsigned short len;                             /* Bytes to read/write    */
  43. {
  44.     char temp[65];                              /* To rename a file       */
  45.     char *dot;                                  /* Find the "."           */
  46.     unsigned short error;                       /* Possible error-code    */
  47.     switch (command)                            /* GOTO in disguise       */
  48.     {
  49. /**************************************************************************/
  50. /*      Open the file for read. If the open fails, return non-zero.       */
  51. /**************************************************************************/
  52.         case OPEN_READ:
  53.         {
  54.             screen (SCR_FIL,NULL,*buffer);
  55.             if ( (*handle = open(*buffer,O_RDONLY|O_BINARY)) != -1 )
  56.             {
  57.                 screen (SCR_FOK,NULL,NULL);     /* Show success          */
  58.                 return JM_NRM;
  59.             }
  60.         screen (SCR_FNF,NULL,NULL);             /* Show failure          */
  61.         return JM_FNF;
  62.         }
  63. /**************************************************************************/
  64. /*       Create a new file. If the file already exists, rename it.        */
  65. /**************************************************************************/
  66.        case CREATE:
  67.         {
  68.             screen (SCR_FIL,NULL,*buffer);
  69.             if ( (*handle = open(*buffer,O_RDONLY|O_BINARY)) != -1 )
  70.             {                                    /* If file already exists */
  71.                 close (*handle);                 /* Close the open file    */
  72.                 strcpy (temp,*buffer);           /* Copy the file name     */
  73.                 dot = strchr (temp, '.');        /* Find "." in string     */
  74.                 strcpy (dot, ".OLD");            /* FILENAME.OLD           */
  75.                 error = rename (*buffer,temp);   /* Rename the file        */
  76.                 if (error)                       /* Can't rename the file  */
  77.                 {
  78.                     screen (SCR_FCR,NULL,temp);  /* Tell user can't rename */
  79.                     return JM_REN;               /* Quit                   */
  80.                 }
  81.                 else
  82.                 {
  83.                    screen (SCR_FRN,NULL,temp);   /* Tell user we renamed   */
  84.                 }
  85.             }
  86. /* Note:                                                                    */
  87. /*     Microsoft's own rules of MS-DOS state that a file being CREATED is   */
  88. /*     open for WRITE (naturally, who would wish to READ from an empty      */
  89. /*     file?).                                                              */
  90. /*     Unix also provides this same logic.                                  */
  91. /*     In the following code, if I did not OR in O_RDWR, I would create a   */
  92. /*     file I can't write to!. If I did not also include the [optional]     */
  93. /*     parameters, S_IWRITE OR S_IREAD, I create a file I can't delete!!!   */
  94. /*     These are implementation bugs.                                       */
  95. /*                                                                          */
  96.             if  ( (*handle = open(               /* Open (create) new file  */
  97.                                *buffer,          /* File name               */
  98.                                 O_CREAT          /* Create new file         */
  99.                                |O_BINARY         /* Binary mode             */
  100.                                |O_RDWR ,         /* Read/write (bug??)      */
  101.                                 S_IWRITE         /* Definite bug            */
  102.                                |S_IREAD)) != -1) /* More of same bug        */
  103.             {
  104.                 screen (SCR_FOK,NULL,temp);      /* Show success            */
  105.                 return JM_NRM;
  106.             }
  107.             else
  108.             {
  109.                 screen (SCR_FCR,NULL,temp);      /* Show failure            */
  110.                 return JM_CRE;
  111.             }
  112.         }
  113. /**************************************************************************/
  114. /*      Write 'len' bytes to the file. Return the actual bytes written    */
  115. /**************************************************************************/
  116.         case WRITE:
  117.         {
  118.         return ( write ( *handle, *buffer, len) );
  119.         }
  120. /**************************************************************************/
  121. /*      Read 'len' bytes from the file. Return the actual bytes read.     */
  122. /**************************************************************************/
  123.         case READ:
  124.         {
  125.         return ( read ( *handle, *buffer, len) );
  126.         }
  127. /**************************************************************************/
  128. /*      Close the file. Return any error-code (ignored).                  */
  129. /**************************************************************************/
  130.         case CLOSE:
  131.         {
  132.         return (close (*handle));
  133.         }
  134. /**************************************************************************/
  135. /*      Delete the file named in 'buffer'. Return any error code.         */
  136. /**************************************************************************/
  137.         case DELETE:
  138.         {
  139.         return (remove (*buffer));
  140.         }
  141.     }
  142. }
  143. /**************************************************************************/
  144. /********************** E N D  O F  M O D U L E  **************************/
  145.